시작

정리

  • 박스 모델 기준으로 자바스크립트에서 얻어올 수 있는 값
    • 해당 박스의 border 바깥 쪽은 offsetTop, offsetLeft
    • border 사이는 clientTop, clientLeft
    • 안에 content는 clientWidth, clientHeight
    • border와 content를 합한 것은 offsetWidth, offsetHeight
    • 보여지는 박스가 아닌 content의 전체 길이는 scrollHeight
    • 현재 스크롤바의 위치는 scrollTop

values

throttle & debounce

  • 이벤트나 요청의 처리 횟수를 컨트롤할때 사용 되는 개념이다
  • 사이트에서 마우스 이동 이벤트를 사용한 throttle, debounce 타임 라인을 보면 이해하는데 약간 도움이 되는 것 같다
  • debounce
    • 들어온 동일한 요청을 하나로 모은 후 마지막 요청만 특정 시간이 지나고나면 실행한다.
    • 여러 요청이 발생 하는데 요청이 다 끝나고 난 후 특정 시간이 지나고 처리할때 사용
  • throttle
    • 특정 시간 주기마다 요청이 수행된다.
    • 여러 요청이 발생하는데 해당 요청을 특정 시간마다 처리할때 사용

구현 로직

  • 전체 영역에서 보여지는 영역을 빼서 보여지지 않은 영역을 구한다
  • 현재 스크롤의 위치와 보여지지 않은 영역의 비율에 100을 곱해서 프로그래스 바 값으로 사용한다
  • 프로그래스 바 요소의 width 값을 해당 값으로 업데이트한다
  • throttle을 사용해 콜백함수가 실행되도록 해주면 된다
  • throttle, debounce할대 특정 시간 값을 너무 크게 잡으면 부자연스러운 동작이 발생해 UX에 좋지 않을 수 있다

코드

const get = (target) => {
  return document.querySelector(target);
};

let timerId;
const throttle = (callback, time) => {
  if (timerId) return;

  timerId = setTimeout(() => {
    callback();
    timerId = undefined;
  }, time);
};

const progressBar = get('.progress-bar');
let throttleDelay = 500;

const onScroll = () => {
  const invisibleContentHeight =
    document.documentElement.scrollHeight - document.documentElement.clientHeight;
  const curScrollPosition = document.documentElement.scrollTop;
  const width = (curScrollPosition / invisibleContentHeight) * 100;

  progressBar.style.width = `${width}%`;
};

window.addEventListener('scroll', () => throttle(onScroll, throttleDelay));

😊